package ctrl;

import java.io.IOException;
import java.io.InputStream;

import javax.microedition.io.Connector;
import javax.microedition.io.HttpConnection;

import net.rim.device.api.io.IOUtilities;
import net.rim.device.api.io.transport.ConnectionDescriptor;
import net.rim.device.api.system.Application;
import net.rim.device.api.system.Bitmap;
import net.rim.device.api.system.Characters;
import net.rim.device.api.system.Display;
import net.rim.device.api.ui.Color;
import net.rim.device.api.ui.Field;
import net.rim.device.api.ui.Graphics;
import net.rim.device.api.ui.TouchEvent;
import net.rim.device.api.ui.component.LabelField;
import weibo.model.User;
import code.Config;
import code.Function;

    
public class UserInforListStyleButtonField extends Field
{
    public static int DRAWPOSITION_TOP = 0;
    public static int DRAWPOSITION_BOTTOM = 1;
    public static int DRAWPOSITION_MIDDLE = 2;
    public static int DRAWPOSITION_SINGLE = 3;
    
    private static final int CORNER_RADIUS = 12;
    
    private static final int HPADDING = Display.getWidth() <= 320 ? 4 : 6;
    private static final int VPADDING = 4;
    
    private static final int COLOR_BACKGROUND = 0xFFFFFF;
    private static final int COLOR_BORDER = 0xBBBBBB; //0x186DEF
    private static final int COLOR_BACKGROUND_FOCUS = 0x0A9000;
    
    private MyLabelField _labelTitle;
    private MyLabelField _labelValue;
    private MyLabelField _labelDescription;
    
    private Bitmap _avatarIcon;
    private Bitmap _rightIcon;
    
    private int _rightOffset;
    private int _leftOffset;
    private int _labelHeight;
    
    private int _drawPosition = -1;

    /**
     * 显示标题、内容和描述，标题在最左边，内容在最右边，描述在标题下边
     * @param title 标题
     * @param value 内容
     * @param description 描述
     */
    public UserInforListStyleButtonField(String title, String value, String description)
    {
    	this(null, title, value, description, null);
	}

    /**
     * 显示标题、内容和一个向右的箭头，标题在最左边，箭头在最右边，内容在箭头左边
     * @param title 标题
     * @param value 内容
     * @param userRightIcon long型，随意指定一个数值即可
     */
    public UserInforListStyleButtonField(String title, String value, long userRightIcon)
    {
        this(null, title, value, null, Bitmap.getBitmapResource("arrow_right_black.png"));
    }

    //public UserInforListStyleButtonField(String title, String value, String description)
    //{
    //  this(null, title, value, description, null);
    //}

    /**
     * 好友样式列表，显示好友头像、好友名字、最近一条微博的预览内容和一个右边的箭头
     * @param user User类包含所需的信息
     */
    public UserInforListStyleButtonField(User user)
    {
        super(USE_ALL_WIDTH | Field.FOCUSABLE);
        
        ConnectionThread _connectionThread = new ConnectionThread();
        if(!_connectionThread.isStarted()) {_connectionThread.start();}
        _connectionThread.fetch(user.getProfileImageUrl());
        
        String screen_name=user.getScreenName();
        String remark=user.getRemark();
        String status_text=user.getStatus()!=null ? user.getStatus().getText() : "（无）";
               
        if(screen_name!=null)
        {
        	remark=remark!=null ? "(" + remark + ")" : "";
        	_labelTitle=new MyLabelField(screen_name+remark+" ("+user.getUserGender()+")");
        	_labelTitle.setFont(Config.FONT_SCREENNAME);
        }
        if(status_text!=null) {_labelDescription=new MyLabelField(status_text, USE_ALL_HEIGHT | USE_ALL_WIDTH | LabelField.ELLIPSIS);}
        _rightIcon=Bitmap.getBitmapResource("arrow_right_black.png");
        _avatarIcon=Bitmap.getBitmapResource("avatar.png");
    }
    
    public UserInforListStyleButtonField(Bitmap icon, String title, String value, String description, Bitmap actionIcon)
    {
        super(USE_ALL_WIDTH | Field.FOCUSABLE);
               
        if(title!=null) {_labelTitle = new MyLabelField(title); _labelTitle.setFont(Config.FONT_SCREENNAME);}
        if(value!=null) {_labelValue=new MyLabelField(value);}
        if(description!=null) {_labelDescription=new MyLabelField(description, USE_ALL_HEIGHT | USE_ALL_WIDTH);}
        if(actionIcon!=null) {_rightIcon = actionIcon;}
        if(icon!=null) {_avatarIcon = icon;}
    }
    
    public void setDrawPosition(int drawPosition) {_drawPosition = drawPosition;}
    
    public void layout(int width, int height)
    {
        _leftOffset = HPADDING;
        if(_avatarIcon!=null) {_leftOffset += _avatarIcon.getWidth() + HPADDING;}
        
        _rightOffset = HPADDING;
        if(_rightIcon!=null) {_rightOffset += _rightIcon.getWidth() + HPADDING;}
        
        _labelTitle.layout(width - _leftOffset - _rightOffset, height);
        _labelHeight = _labelTitle.getHeight();
        
        if(_labelValue!=null) {_labelValue.layout(width- _leftOffset - _rightOffset, height);}
        
        if(_labelDescription!=null)
        {
        	_labelDescription.layout( width - _leftOffset - _rightOffset, height );
        	_labelHeight+=_labelDescription.getHeight();
        }
        
        if(_avatarIcon!=null) {_labelHeight=(_avatarIcon.getHeight()>=_labelHeight) ? _avatarIcon.getHeight() : _labelHeight;}

        setExtent(width, _labelHeight+10);
    }
    
    public void setTitleText(String text)
    {
    	_labelTitle.setText(text);
        updateLayout();
    }
    
    public void setValueText(String text)
    {
    	_labelValue.setText(text);
    	updateLayout();
	}
    
    public void setDescription(String text)
    {
    	_labelDescription.setText(text);
    	updateLayout();
    }
    
    public void setAvatarIcon(byte[] icon)
    {
    	_avatarIcon=Bitmap.createBitmapFromBytes(icon, 0, -1, 1);
    }
    
    protected void paint(Graphics g)
    {
        // Avatar Bitmap
        if(_avatarIcon!=null)
        {
            g.drawBitmap(HPADDING, (getHeight()-_avatarIcon.getHeight())/2, _avatarIcon.getWidth(), _avatarIcon.getHeight(), _avatarIcon, 0, 0);
        }
        
        // Title Text
        try {
            g.pushRegion(_leftOffset, (getHeight() - _labelHeight)/2, getWidth() - _leftOffset - _rightOffset, _labelTitle.getHeight(), 0, 0);
            //_labelTitle.setFont(Config.FONT_SCREENNAME);
            _labelTitle.paint(g);
        } finally {
            g.popContext();
        }
        
        // Right Bitmap
        if(_rightIcon != null)
        {
        	Bitmap action= g.isDrawingStyleSet(Graphics.DRAWSTYLE_FOCUS) ? Bitmap.getBitmapResource("arrow_right.png") : Bitmap.getBitmapResource("arrow_right_black.png");
            g.drawBitmap(getWidth() - HPADDING - action.getWidth(), (getHeight() - action.getHeight()) / 2, action.getWidth(), action.getHeight(), action, 0, 0);
        }
        
        // Value Text
        if(_labelValue !=null)
        {
        	try {
        		g.pushRegion(getWidth() - _labelValue.getWidth()-_rightOffset,(getHeight() - _labelValue.getHeight())/2,_labelValue.getWidth(), _labelValue.getHeight(),0,0);
        		_labelValue.paint(g);
        	} finally{
        		g.popContext();
        	}
        }
        
        // Description Text
        if(_labelDescription!=null)
        {
        	try {
        		Graphics oldG=g;
        		g.pushRegion(_leftOffset+HPADDING,getHeight()-_labelDescription.getHeight()-VPADDING,getWidth()-_leftOffset-_rightOffset,_labelDescription.getHeight(),0,0);
        		g.setColor(g.isDrawingStyleSet(Graphics.DRAWSTYLE_FOCUS) ? Color.WHITE : Color.GRAY);
        		//g.setFont(Font.getDefault().derive(Font.PLAIN, Font.getDefault().getHeight(Ui.UNITS_pt)-1,Ui.UNITS_pt));
        		_labelDescription.paint(g);
        		
        		g=oldG;
        	} finally{
        		g.popContext();
        	}
        }
    }
    
    protected void paintBackground(Graphics g)
    {
        if(_drawPosition < 0)
        {
            super.paintBackground(g);
            return;
        }
        
        int oldColour = g.getColor();
        
        int background = g.isDrawingStyleSet(Graphics.DRAWSTYLE_FOCUS) ? COLOR_BACKGROUND_FOCUS : COLOR_BACKGROUND;
        
        try {
            if(_drawPosition == 0)
            {
                // Top
                g.setColor(background);
                g.fillRoundRect(0, 0, getWidth(), getHeight() + CORNER_RADIUS, CORNER_RADIUS, CORNER_RADIUS);
                g.setColor( COLOR_BORDER );
                g.drawRoundRect(0, 0, getWidth(), getHeight() + CORNER_RADIUS, CORNER_RADIUS, CORNER_RADIUS);
                g.drawLine(0, getHeight() - 1, getWidth(), getHeight() - 1);
            } else if( _drawPosition == 1 ) {
                // Bottom 
                g.setColor(background);
                g.fillRoundRect(0, -CORNER_RADIUS, getWidth(), getHeight() + CORNER_RADIUS, CORNER_RADIUS, CORNER_RADIUS);
                g.setColor( COLOR_BORDER );
                g.drawRoundRect(0, -CORNER_RADIUS, getWidth(), getHeight() + CORNER_RADIUS, CORNER_RADIUS, CORNER_RADIUS);
            } else if(_drawPosition == 2) {
                // Middle
                g.setColor(background);
                g.fillRoundRect(0, -CORNER_RADIUS, getWidth(), getHeight() + 2 * CORNER_RADIUS, CORNER_RADIUS, CORNER_RADIUS);
                g.setColor( COLOR_BORDER );
                g.drawRoundRect(0, -CORNER_RADIUS, getWidth(), getHeight() + 2 * CORNER_RADIUS, CORNER_RADIUS, CORNER_RADIUS);
                g.drawLine(0, getHeight() - 1, getWidth(), getHeight() - 1);
            } else {
                // Single
                g.setColor(background);
                g.fillRoundRect(0, 0, getWidth(), getHeight(), CORNER_RADIUS, CORNER_RADIUS);
                g.setColor(COLOR_BORDER);
                g.drawRoundRect(0, 0, getWidth(), getHeight(), CORNER_RADIUS, CORNER_RADIUS);
            }
        } finally {
            g.setColor(oldColour);
        }
    }
    
    protected void drawFocus(Graphics g, boolean on)
    {
        if(_drawPosition < 0)
        {
            super.drawFocus(g, on);
        } else {
            boolean oldDrawStyleFocus = g.isDrawingStyleSet(Graphics.DRAWSTYLE_FOCUS);
            try {
                if(on)
                {
                	g.setColor(Color.WHITE);
                    g.setDrawingStyle(Graphics.DRAWSTYLE_FOCUS, true);
                }
                
                paintBackground(g);
                paint(g);
            } finally {
                g.setDrawingStyle(Graphics.DRAWSTYLE_FOCUS, oldDrawStyleFocus);
            }
        }
    }
    
    protected boolean keyChar(char character, int status, int time) 
    {
        if(character == Characters.ENTER)
        {
            clickButton();
            return true;
        }
        
        return super.keyChar(character, status, time);
    }
    
    protected boolean navigationClick(int status, int time) 
    {
        clickButton(); 
        return true;    
    }
    
    protected boolean trackwheelClick(int status, int time)
    {        
        clickButton();    
        return true;
    }
    
    protected boolean invokeAction(int action) 
    {
        switch(action)
        {
            case ACTION_INVOKE:
                clickButton(); 
                return true;
        }
        
        return super.invokeAction(action);
    }
         
    public void clickButton() {fieldChangeNotify(0);}
       
    protected boolean touchEvent(TouchEvent message)
    {
        int x = message.getX(1);
        int y = message.getY(1);
        if(x < 0 || y < 0 || x > getExtent().width || y > getExtent().height) {return false;}
        
        switch(message.getEvent())
        {
        	case TouchEvent.CLICK:
                clickButton();
                return true;
        }
        
        return super.touchEvent(message);
    }

    public void setDirty(boolean dirty) {}
    public void setMuddy(boolean muddy) {}
    
    private class ConnectionThread extends Thread
    {
        private static final int TIMEOUT = 500;
        private String _theUrl;
        private volatile boolean _fetchStarted = false;
        private volatile boolean _stop = false;
        private byte[] data;

        private String getUrl() {return _theUrl;}
        
        private boolean isStarted() {return _fetchStarted;}            
     
        private void fetch(String url)
        {
            _fetchStarted = true;
            _theUrl = url;
        }

        private void stop() {_stop = true;}

        public void run()
        {
            for(;;)
            {
                while( !_fetchStarted && !_stop)  
                {
                    try {sleep(TIMEOUT);} catch (InterruptedException e) {Function.errorDialog(UserInforListStyleButtonField.class.getName() + "\n\n" + "Thread#sleep threw " + e.toString());}
                }
                
                if (_stop) {return;}
                    
                MyConnectionFactory factory=new MyConnectionFactory();
                ConnectionDescriptor descriptor=factory.getConnection(getUrl());
                if(descriptor==null)
                {
                	_fetchStarted=false;
                	stop();
                	return;
                }
                
                HttpConnection httpConnection=(HttpConnection) descriptor.getConnection();
                InputStream inputStream=null;
                
                try 
                {               
					inputStream=httpConnection.openInputStream();
					if(inputStream.available()>0)
					{
						data=IOUtilities.streamToBytes(inputStream);
						
						if(data.length==httpConnection.getLength())
						{
							synchronized(Application.getEventLock())
							{
								Application.getApplication().invokeLater(new Runnable()
								{
									public void run()
									{
										setAvatarIcon(data);
										updateLayout();
									}
								});
							}
							
			                _fetchStarted = false;        
			                stop();
						}
					}
                } catch (IOException e) {
                } finally {
                	if(inputStream!=null) {try {inputStream.close();} catch (Exception e2) {}}
                	if(httpConnection!=null) {try {httpConnection.close();} catch (Exception e2) {}}
                }
            }
        }
    }
}